-- This file is part of the Fantasy Grounds Open Foundation Ruleset project. 
-- For the latest information, see http://www.fantasygrounds.com/
--
-- Copyright 2008 SmiteWorks Ltd.
--
-- This file is provided under the Open Game License version 1.0a
-- Refer to the license.html file for the full license text
--
-- All producers of work derived from this material are advised to
-- familiarize themselves with the license, and to take special
-- care in providing the definition of Product Identity (as specified
-- by the OGL) in their products.
--
-- All material submitted to the Open Foundation Ruleset project must
-- contain this notice in a manner applicable to the source file type.


function update()
	setValue((ranknode.getValue() + plannedranknode.getValue()) + 0.5 * (halfranknode.getValue() + plannedhalfranknode.getValue()));
	
	if plannedranknode.getValue() ~= 0 or plannedhalfranknode.getValue() ~= 0 then
		setColor("ffbb0000");
	else
		setColor(nil);
	end

	window.windowlist.skillPointsChanged();
end

-- Helper function to get class skill status from state control
function isClassSkill()
	return window["state"].isClassSkill();
end

function checkAndSet(value)
	if not window.windowlist.directadjustment then
		-- Round down to nearest possible skill rank, i.e. increments of .5
		value = math.floor(value * 2) / 2;

		-- Calculate the planned ranks
		local ranks = ranknode.getValue();
		local halfranks = halfranknode.getValue();
		
		local plannedranks = 0;

		if isClassSkill() then
			local newranks = value - ranks - halfranks * 0.5;

			if newranks >= 0 and newranks == math.floor(newranks) then
				plannedranks = newranks;
			end
		else
			local newhalfranks = 2 * (value - ranks - halfranks * 0.5);
			
			if newhalfranks >= 0 then
				plannedranks = newhalfranks;
			end
		end
		
		-- Make sure the value doesn't go over the available skill points or the maximum rank
		local maxranks = levelnode.getValue() + 3;

		local totalplanned = 0;
		for k,w in ipairs(window.windowlist.getWindows()) do
			if w ~= window then
				totalplanned = totalplanned + w.getDatabaseNode().getChild("plannedranks").getValue();
				totalplanned = totalplanned + w.getDatabaseNode().getChild("plannedhalfranks").getValue();
			end
		end
		
		if availablenode.getValue() - totalplanned < plannedranks then
			maxranks = availablenode.getValue() - totalplanned + ranks + halfranks;
		end
		
--		print("planned " .. plannedranks .. ", total " .. totalplanned .. ", ranks " .. ranks .. ", half " .. halfranks .. ", max " .. maxranks);
		
		if plannedranks + ranks + halfranks > maxranks then
			plannedranks = maxranks - ranks - halfranks;
		end
		if plannedranks < 0 then
			plannedranks = 0;
		end

		-- Adjust values
		if isClassSkill() then
			plannedranknode.setValue(plannedranks);
		else
			plannedhalfranknode.setValue(plannedranks);
		end
	else		
		if isClassSkill() then
			local newranks = value - halfranknode.getValue() * 0.5;
			
			-- Adjust ranks, fall through to previous values if negative or fractional
			if newranks >= 0 and newranks == math.floor(newranks) then
				ranknode.setValue(newranks);
			end
		else
			local newhalfranks = 2 * (value - ranknode.getValue());
			
			-- Adjust half ranks, fall through to previous values if negative
			if newhalfranks >= 0 then
				halfranknode.setValue(newhalfranks);
			end
		end
	end

	update();
end

function onValueChanged()
	checkAndSet(getValue());
end

function onWheel(notches)
	if isClassSkill() then
		checkAndSet(getValue() + notches);
	else
		checkAndSet(getValue() + notches * 0.5);
	end
	
	return true;
end

function onInit()
	ranknode = window.getDatabaseNode().createChild("ranks", "number");
	halfranknode = window.getDatabaseNode().createChild("halfranks", "number");
	plannedranknode = window.getDatabaseNode().createChild("plannedranks", "number");
	plannedhalfranknode = window.getDatabaseNode().createChild("plannedhalfranks", "number");
	
	ranknode.onUpdate = update;
	halfranknode.onUpdate = update;
	plannedranknode.onUpdate = update;
	plannedhalfranknode.onUpdate = update;
	
	levelnode = window.windowlist.window.getDatabaseNode().createChild("characterlevel", "number");
	availablenode = window.windowlist.window.getDatabaseNode().createChild("skillpoints.unspent", "number");
	
	update();
end
